package cn.com.zero.front.auth.service.impl;

import cn.com.zero.base.constant.ZeroRegexPatternConstants;
import cn.com.zero.base.exception.ErrorCodeException;
import cn.com.zero.base.service.BaseService;
import cn.com.zero.base.util.RegexUtil;
import cn.com.zero.base.util.SensitiveInfoUtil;
import cn.com.zero.file.client.MinioTemplate;
import cn.com.zero.file.service.IFileService;
import cn.com.zero.file.vo.FileInfo;
import cn.com.zero.front.auth.constant.FrontAuthConstants;
import cn.com.zero.front.auth.mapper.IRealNameMapper;
import cn.com.zero.front.auth.po.AuthenticationApplyPO;
import cn.com.zero.front.auth.po.AuthenticationInfoPO;
import cn.com.zero.front.auth.service.IRealNameVerifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author xiongxj
 * @version 1.0.0
 * @Description 实名认证service实现类
 * @createTime 2023/3/16 14:25
 */
@Service
public class RealNameVerifyService extends BaseService implements IRealNameVerifyService {

    private IRealNameMapper realNameMapper;
    private IFileService fileService;

    @Override
    public boolean isExistCardNo(String cardNo, Integer cardType) {
        String encryptCardNo = SensitiveInfoUtil.encryptCardNo(cardNo);
        int count = realNameMapper.queryAuthenticationCount(encryptCardNo, cardType);
        return count > 0;
    }

    @Override
    public void addAuthenticationApply(String userId, String realName, Integer cardType, String cardNo, Date validity,
                                       String frontDocument, String backDocument, String handDocument) {
        // 判断该用户是否有待审核的实名信息
        int applyCount = realNameMapper.getAuthenticationApplyCount(userId);
        if (applyCount > 0) {
            throw new ErrorCodeException(-20005L); // 存在待审核的实名申请
        }
        // 判断用户是否已经实名
        AuthenticationInfoPO authenticationInfoPO = realNameMapper.queryAuthenticationInfo(userId, false);
        if (authenticationInfoPO != null) {
            throw new ErrorCodeException(-20006L); // 用户已实名
        }
        // 判断证件号是否存在
        int count = realNameMapper.queryAuthenticationCount(cardNo, cardType);
        if (count > 0) {
            throw new ErrorCodeException(-20007L); // 证件号码已存在
        }

        AuthenticationApplyPO authenticationApplyPo = new AuthenticationApplyPO();
        authenticationApplyPo.setUserId(userId);
        authenticationApplyPo.setFrontDocument(frontDocument);
        authenticationApplyPo.setBackDocument(backDocument);
        authenticationApplyPo.setHandDocument(handDocument);
        authenticationApplyPo.setCardType(cardType);
        authenticationApplyPo.setValidity(validity);
        // 加密展示真实姓名
        String showRealName = SensitiveInfoUtil.encodeName(realName);
        authenticationApplyPo.setRealName(realName);
        authenticationApplyPo.setShowRealName(showRealName);
        // 加密证件号码
        String encryptCardNo = SensitiveInfoUtil.encryptCardNo(cardNo);
        // 加密展示证件号码
        String showCardNo = SensitiveInfoUtil.encodeCardNo(cardNo);
        authenticationApplyPo.setCardNo(encryptCardNo);
        authenticationApplyPo.setShowCardNo(showCardNo);

        realNameMapper.insertAuthenticationApply(authenticationApplyPo);
    }

    @Override
    public AuthenticationApplyPO queryAuthenticationApply(String userId) {
        return realNameMapper.queryAuthenticationApply(userId);
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void updateAuthenticationInfo(String userId, Date validity, String frontDocument, String backDocument, String handDocument) {
        // 查询客户实名信息(加锁)
        AuthenticationInfoPO authenticationInfoPo = realNameMapper.queryAuthenticationInfo(userId, true);
        if (authenticationInfoPo == null) {
            logger.info("修改实名申请失败，原因：用户实名信息为空，用户ID：{}", userId);
            throw new ErrorCodeException(-20008L); // 用户实名信息为空
        }

        // 判断该用户是否有待审核的实名信息
        int applyCount = realNameMapper.getAuthenticationApplyCount(userId);
        if (applyCount > 0) {
            throw new ErrorCodeException(-20005L);
        }

        AuthenticationApplyPO authenticationApplyPo = new AuthenticationApplyPO();
        authenticationApplyPo.setRealName(authenticationInfoPo.getRealName());
        authenticationApplyPo.setShowRealName(authenticationInfoPo.getShowRealName());
        authenticationApplyPo.setCardNo(authenticationInfoPo.getCardNo());
        authenticationApplyPo.setShowCardNo(authenticationInfoPo.getShowCardNo());
        authenticationApplyPo.setCardType(authenticationInfoPo.getCardType());

        authenticationApplyPo.setUserId(userId);
        authenticationApplyPo.setFrontDocument(frontDocument);
        authenticationApplyPo.setBackDocument(backDocument);
        authenticationApplyPo.setHandDocument(handDocument);
        authenticationApplyPo.setValidity(validity);

        realNameMapper.insertAuthenticationApply(authenticationApplyPo);
    }

    @Override
    public String uploadAuthenticationApply(MultipartFile idPhoto) {
        // 上传文件到私有存储桶
        FileInfo fileInfo = fileService.upload(idPhoto, MinioTemplate.BUCKET_DEFAULT_PRIVATE, FrontAuthConstants.RELATIVE_PATH_ID_PhOTO);
        return fileInfo.getRelativeFilePath();
    }

    @Autowired
    public void setRealNameMapper(IRealNameMapper realNameMapper) {
        this.realNameMapper = realNameMapper;
    }

    @Resource
    public void setFileService(IFileService fileService) {
        this.fileService = fileService;
    }
}
